gdk/wayland: Listen to wl_surface events on tablet cursors
authorCarlos Garnacho <carlosg@gnome.org>
Thu, 18 Apr 2019 17:31:55 +0000 (19:31 +0200)
committerCarlos Garnacho <carlosg@gnome.org>
Thu, 18 Apr 2019 17:27:29 +0000 (19:27 +0200)
And update the surface accordingly (eg. scale on hidpi). The mechanism
that did that for wl_pointer has been made generic so it can be shared
with tablets too.

Closes: https://gitlab.gnome.org/GNOME/gtk/issues/1675
gdk/wayland/gdkdevice-wayland.c

index 2506bd2c3eb0d7b861d212421d8fe2a402703603..6fb0b1f6dce89472a043c83cfcf750ae338fa211 100644 (file)
@@ -284,6 +284,9 @@ struct _GdkWaylandDevicePadClass
 };
 
 static void gdk_wayland_device_pad_iface_init (GdkDevicePadInterface *iface);
+static void init_pointer_data (GdkWaylandPointerData *pointer_data,
+                               GdkDisplay            *display_wayland,
+                               GdkDevice             *master);
 static void pointer_surface_update_scale (GdkDevice *device);
 
 #define GDK_TYPE_WAYLAND_DEVICE_PAD (gdk_wayland_device_pad_get_type ())
@@ -2878,6 +2881,8 @@ tablet_handle_done (void                 *data,
                                 NULL);
 
   tablet->master = master;
+  init_pointer_data (&tablet->pointer_info, display, tablet->master);
+
   tablet->stylus_device = stylus_device;
   tablet->eraser_device = eraser_device;
 
@@ -4325,14 +4330,11 @@ tablet_seat_handle_tablet_added (void                      *data,
                                  struct zwp_tablet_v2      *wp_tablet)
 {
   GdkWaylandSeat *seat = data;
-  GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
   GdkWaylandTabletData *tablet;
 
   tablet = g_new0 (GdkWaylandTabletData, 1);
   tablet->seat = GDK_SEAT (seat);
-  tablet->pointer_info.current_output_scale = 1;
-  tablet->pointer_info.pointer_surface =
-    wl_compositor_create_surface (display_wayland->compositor);
+
   tablet->wp_tablet = wp_tablet;
 
   seat->tablets = g_list_prepend (seat->tablets, tablet);
@@ -4466,16 +4468,28 @@ pointer_surface_enter (void              *data,
                        struct wl_output  *output)
 
 {
-  GdkWaylandSeat *seat = data;
+  GdkDevice *device = data;
+  GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
+  GdkWaylandTabletData *tablet;
 
   GDK_DISPLAY_NOTE (seat->display, EVENTS,
             g_message ("pointer surface of seat %p entered output %p",
                        seat, output));
 
-  seat->pointer_info.pointer_surface_outputs =
-    g_slist_append (seat->pointer_info.pointer_surface_outputs, output);
+  tablet = gdk_wayland_seat_find_tablet (seat, device);
 
-  pointer_surface_update_scale (seat->master_pointer);
+  if (tablet)
+    {
+      tablet->pointer_info.pointer_surface_outputs =
+        g_slist_append (seat->pointer_info.pointer_surface_outputs, output);
+    }
+  else
+    {
+      seat->pointer_info.pointer_surface_outputs =
+        g_slist_append (seat->pointer_info.pointer_surface_outputs, output);
+    }
+
+  pointer_surface_update_scale (device);
 }
 
 static void
@@ -4483,16 +4497,28 @@ pointer_surface_leave (void              *data,
                        struct wl_surface *wl_surface,
                        struct wl_output  *output)
 {
-  GdkWaylandSeat *seat = data;
+  GdkDevice *device = data;
+  GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (gdk_device_get_seat (device));
+  GdkWaylandTabletData *tablet;
 
   GDK_DISPLAY_NOTE (seat->display, EVENTS,
             g_message ("pointer surface of seat %p left output %p",
                        seat, output));
 
-  seat->pointer_info.pointer_surface_outputs =
-    g_slist_remove (seat->pointer_info.pointer_surface_outputs, output);
+  tablet = gdk_wayland_seat_find_tablet (seat, device);
+
+  if (tablet)
+    {
+      tablet->pointer_info.pointer_surface_outputs =
+        g_slist_remove (seat->pointer_info.pointer_surface_outputs, output);
+    }
+  else
+    {
+      seat->pointer_info.pointer_surface_outputs =
+        g_slist_remove (seat->pointer_info.pointer_surface_outputs, output);
+    }
 
-  pointer_surface_update_scale (seat->master_pointer);
+  pointer_surface_update_scale (device);
 }
 
 static const struct wl_surface_listener pointer_surface_listener = {
@@ -4860,6 +4886,23 @@ gdk_wayland_seat_init (GdkWaylandSeat *seat)
 {
 }
 
+static void
+init_pointer_data (GdkWaylandPointerData *pointer_data,
+                   GdkDisplay            *display,
+                   GdkDevice             *master)
+{
+  GdkWaylandDisplay *display_wayland;
+
+  display_wayland = GDK_WAYLAND_DISPLAY (display);
+
+  pointer_data->current_output_scale = 1;
+  pointer_data->pointer_surface =
+    wl_compositor_create_surface (display_wayland->compositor);
+  wl_surface_add_listener (pointer_data->pointer_surface,
+                           &pointer_surface_listener,
+                           master);
+}
+
 void
 _gdk_wayland_display_create_seat (GdkWaylandDisplay *display_wayland,
                                   guint32            id,
@@ -4898,14 +4941,8 @@ _gdk_wayland_display_create_seat (GdkWaylandDisplay *display_wayland,
   wl_data_device_add_listener (seat->data_device,
                                &data_device_listener, seat);
 
-  seat->pointer_info.current_output_scale = 1;
-  seat->pointer_info.pointer_surface =
-    wl_compositor_create_surface (display_wayland->compositor);
-  wl_surface_add_listener (seat->pointer_info.pointer_surface,
-                           &pointer_surface_listener,
-                           seat);
-
   init_devices (seat);
+  init_pointer_data (&seat->pointer_info, display, seat->master_pointer);
 
   if (display_wayland->tablet_manager)
     {